package de.dhbw.vs.permachat.server.rest;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/*import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;*/
import javax.ws.rs.Consumes;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;

import com.javadocmd.simplelatlng.LatLng;
import com.javadocmd.simplelatlng.LatLngTool;
import com.javadocmd.simplelatlng.util.LengthUnit;

import de.dhbw.vs.permachat.server.persistence.ChatDao;
import de.dhbw.vs.permachat.server.persistence.entities.ChatMessage;
import de.dhbw.vs.permachat.server.persistence.entities.ChatRoom;

@Path("/chat/rooms")
//@ManagedBean
/*@Named
@RequestScoped*/
@Produces(MediaType.APPLICATION_JSON)
public class ChatService {
	
	/*@Inject*/
	ChatDao dao;
	
	public ChatService(){
		this.dao = new ChatDao();
	}
	
	@GET
	@Path("initialize")
	public void initialize(){
		this.dao.createOrUpdateChatRoom("Mannheim", 49.49, 8.48);
		this.dao.createOrUpdateChatRoom("Stuttgart", 48.780, 9.192);
		this.dao.close();
		this.dao = new ChatDao();
		this.dao.createOrUpdateChatRoom("Berlin", 52.52564, 13.40185);
		this.dao.createOrUpdateChatRoom("Ludwigsburg", 48.89, 9.19);
		this.dao.close();
		this.dao = new ChatDao();
		this.dao.createOrUpdateChatRoom("Kornwestheim", 48.861214, 9.179764);
		this.dao.createOrUpdateChatRoom("Dresden", 51.05, 13.7333);
		this.dao.close();
		this.dao = new ChatDao();
		this.dao.createOrUpdateChatRoom("Koeln", 50.94, 6.95);
		this.dao.close();
		
		/*ChatUser user01 = this.dao.getOrCreateChatUser("user01");
		ChatUser user02 = this.dao.getOrCreateChatUser("user02");
		ChatUser user03 = this.dao.getOrCreateChatUser("user03");
		
		this.dao.postMessage(user01, room01, new Date().toString() + "hello, I am user01");
		this.dao.postMessage(user02, room01, new Date().toString() + "hello, I am user02");
		
		this.dao.postMessage(user02, room02, new Date().toString() + "hello, I am user02");
		this.dao.postMessage(user03, room02, new Date().toString() + ": hello, I am user03");*/
	}
	
	@GET
	public List<ChatRoom> listChatRooms(@QueryParam("latitude") Double pLatitude, @QueryParam("longitude") Double pLongitude){
		if(pLatitude == null || pLongitude == null){
			return this.dao.listChatRooms();
		} else{
			final LatLng userLocation = new LatLng(pLatitude, pLongitude);
			
			List<ChatRoom> chatRooms = this.dao.listChatRooms();
			Collections.sort(chatRooms, new Comparator<ChatRoom>() {

				@Override
				public int compare(ChatRoom r1, ChatRoom r2) {
					if(r1 == null && r2 == null){
						return 0;
					} else{
						if(r1 == null){
							return -1;
						} else{
							if(r2 == null){
								return 1;
							} else{
								LatLng r1Location = new LatLng(r1.getLatitude(), r1.getLongitude());
								double r1Distance = LatLngTool.distance(userLocation, r1Location, LengthUnit.METER);
								
								LatLng r2Location = new LatLng(r2.getLatitude(), r2.getLongitude());
								double r2Distance = LatLngTool.distance(userLocation, r2Location, LengthUnit.METER);
								
								return Double.compare(r1Distance, r2Distance);
							}
						}
					}
				}
				
			});
			
			this.dao.close();
			return chatRooms;
		}
	}
	
	@GET
	@Path("{roomName}/messages")
	public List<ChatMessage> listChatMessages(@PathParam("roomName") String pChatRoom, @DefaultValue("-1") @QueryParam("count") Integer pCount, @DefaultValue("-1") @QueryParam("lastId") Long pLastId){
		List<ChatMessage> chatMessages = this.dao.listChatMessages(pChatRoom, pCount, pLastId);
		this.dao.close();
		return chatMessages;
	}
	
	/*@POST
	@Path("{roomName}/messages")
	public void postChatMessage(@FormParam("user") String pUser, @PathParam("roomName") String pChatRoom, @FormParam("message") String pMessage){
		this.dao.postMessage(pUser, pChatRoom, pMessage);
	}*/
	
	@POST
	@Path("{roomName}/messages")
	@Consumes(MediaType.APPLICATION_JSON)
	public void postChatMessage(@PathParam("roomName") String pChatRoom, ChatMessage pMessage){
		this.dao.postMessage(pMessage.getChatUser(), pChatRoom, pMessage.getTextMessage());
		this.dao.close();
	}
	
	@POST
	@Consumes(MediaType.APPLICATION_JSON)
	public void createChatRoom(ChatRoom pChatRoom){
		this.dao.createOrUpdateChatRoom(pChatRoom.getName(), pChatRoom.getLatitude(), pChatRoom.getLongitude());
		this.dao.close();
	}
	
	@GET
	@Path("nearest")
	public ChatRoom getNearestChatRoom(@QueryParam("latitude") double pLatitude, @QueryParam("longitude") double pLongitude){
		LatLng userLocation = new LatLng(pLatitude, pLongitude);
		
		List<ChatRoom> chatRooms = this.dao.listChatRooms();
		ChatRoom nearestRoom = null;
		double nearestDistance = Double.MAX_VALUE;
		
		for(ChatRoom roomToCheck : chatRooms){
			LatLng locationToCheck = new LatLng(roomToCheck.getLatitude(), roomToCheck.getLongitude());
			double roomToCheckDistance = LatLngTool.distance(userLocation, locationToCheck, LengthUnit.METER);
			
			if(roomToCheckDistance < nearestDistance){
				nearestDistance = roomToCheckDistance;
				nearestRoom = roomToCheck;
			}
			
		}
		
		this.dao.close();
		return nearestRoom;
	}
	
	
}
